"""
Case Type   : cm
Case Name   : cm_ctl build重建，基础参数验证
Create At   : 2024-07
Owner       : haomeng
Description :
    1、查看集群状态
    2、停止备1节点
    3、重建备1节点
    4、kill掉备节点dn进程，查看集群状态
    5、恢复环境
    6、kill掉主节点dn进程，查看集群状态
    7、恢复集群初始状态
Expect      :
    1、集群所有节点状态正常，显示Normal
    2、停止备1节点成功
    3、重建备1节点成功
    4、kill掉备节点dn进程成功，备节点异常
    5、恢复备节点状态成功
    6、kill掉主节点dn进程成功，原主节点异常，，集群内产生新主
    7、恢复集群状态成功
History     :
"""

import os
import time
import unittest

from testcase.utils.CommonSH import CommonSH
from testcase.utils.Common import Common
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro

Primary_SH = CommonSH('PrimaryDbUser')


@unittest.skipIf(3 != Primary_SH.get_node_num(), '需1主2备环境，否则不执行')
class CmCtl(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.comsh = CommonSH('PrimaryDbUser')
        self.pri_user = Node('PrimaryDbUser')
        self.sta1_user = Node('Standby1DbUser')
        self.com = Common()
        self.constant = Constant()

    def test_cm(self):
        text = '----step1:查看集群状态; expect:集群状态正常,DN主在节点1----'
        self.log.info(text)

        status = self.comsh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)
        self.assertIn("cluster_state   : Normal", status, '集群状态异常')

        text = '----step2:停止备1节点; expect:停止节点成功----'
        self.log.info(text)

        stop_dn = self.comsh.exec_cm_ctl('stop', '-n 2',
                                         f'-D {macro.DB_INSTANCE_PATH}')
        self.log.info(stop_dn)
        self.assertIn(self.constant.cm_stop_instance_success_msg, stop_dn, '停止集群失败')

        text = '-----step3:执行重建备机操作,查看集群状态  expect:重建备机成功,集群状态正常-----'
        self.log.info(text)

        rebuild = self.comsh.exec_cm_ctl('build', '-n 2',
                                         f'-D {macro.DB_INSTANCE_PATH} -b full')
        self.log.info(rebuild)
        self.assertIn()
        time.sleep(60)

        status = self.comsh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)
        self.assertIn("cluster_state   : Normal", status, '集群状态异常')

        text = '-----step4:kill掉备节点dn进程，查看集群状态  expect:kill掉备节点dn进程成功，备节点异常-----'
        self.log.info(text)

        sta1_dn_pid = self.com.get_pid(self.sta1_user, 'bin/gaussdb')
        self.log.info(sta1_dn_pid)
        kill_dn = self.sta1_user.sh(f'kill -9 {sta1_dn_pid}').result()
        self.log.info(kill_dn)
        self.assertEqual('', kill_dn, 'kill备节点dn进程失败')

        text = '-----step5:查看集群状态，恢复备节点状态  expect:备节点异常，拉起恢复备机成功-----'
        self.log.info(text)

        status = self.comsh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)
        sta_status = status.splitlines()[-1].split('|')[1]
        self.assertIn('stopped', sta_status, '备节点正常')

        start_sta = self.comsh.exec_cm_ctl('start', '-n 2',
                                           f'-D {macro.DB_INSTANCE_PATH}')
        self.log.info(start_sta)
        self.log.info(self.constant.cm_start_instance_success_msg, start_sta, '拉起备节点失败')

        status = self.comsh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)
        self.assertIn("cluster_state   : Normal", status, '集群状态异常')

        text = '-----step6:kill掉主节点dn进程，查看集群状态  expect:成功，原主节点异常，，集群内产生新主-----'
        self.log.info(text)

        pri_dn_pid = self.com.get_pid(self.pri_user, 'bin/gaussdb')
        self.log.info(pri_dn_pid)
        kill_dn = self.pri_user.sh(f'kill -9 {pri_dn_pid}').result()
        self.log.info(kill_dn)
        self.assertEqual('', kill_dn, 'kill主节点dn进程失败')

        status = self.comsh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)
        pri_status = status.splitlines()[-1].split('|')[0]
        self.assertIn('stopped', pri_status, '主节点状态正常')

    def tearDown(self):
        text = '-----step7:恢复集群初始状态  expect:恢复成功，集群状态正常-----'
        self.log.info(text)

        start = self.comsh.exec_cm_ctl('start')
        self.log.info(start)

        status = self.comsh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)
        p_status = status.splitlines()[-1].split('|')[0].split('6001')[-1]
        if 'Primary' in p_status:
            self.log.info('---集群状态正常，无需恢复为初始状态---')
        else:
            recovery = Primary_SH.exec_cm_ctl(mode='switchover', param='-a')
            self.log.info(recovery)

            self.assertIn(self.constant.cm_switchover_success_msg, recovery,
                          '执行失败' + text)

        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        self.assertIn('cluster_state   : Normal', status, '执行失败' + text)
        self.assertIn('P Primary Normal',
                      status.splitlines()[-1].split('|')[0].split('6001')[-1],
                      '执行失败' + text)
        self.assertIn('S Standby Normal',
                      status.splitlines()[-1].split('|')[1].split('6002')[-1],
                      '执行失败' + text)
        self.log.info(f'-----{os.path.basename(__file__)} end-----')
